package threadDemo;

import org.apache.log4j.Logger;

import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * Created by ${张英杰} on 2022-11-03 14:42:17
 * 多线程 watch 没有加 feed 机制。暂时只 get判断
 */
public class WatchDogMutilThread extends Thread{
    private static final Logger logger = Logger.getLogger(WatchDogMutilThread.class);

    private static final String TAG = "watchDogMutilThread";
    final Object Waiter = new Object();
    final int mTimeout;
    boolean mFeeded = false;
    Boolean mFound = false;
    private CopyOnWriteArrayList<String> threadNames = new CopyOnWriteArrayList<>();
    private ConcurrentHashMap<String,Boolean> mFeedMap = new ConcurrentHashMap<>();


    private WatchDogInterface mWatchDogInterface;

    public WatchDogMutilThread(int timeout, WatchDogInterface watchDogInterface) {
        super("WatchDog_MutilThread");
        mTimeout = timeout;
        mWatchDogInterface = watchDogInterface;
    }

    @Override
    public void run() {
        while (true) {
            try {
                synchronized (Waiter) {
                    Waiter.wait(mTimeout);
//                    if (mFeeded) {//多线程
//                        mFeeded = false;
//                        continue;
//                    }
                    logger.info("run: ");
                }
                    Map<Thread, StackTraceElement[]> stacks = Thread.getAllStackTraces();
                    Set<Thread> set = stacks.keySet();
                    HashSet<String> names = new HashSet<>();
                    for (Thread key : set) {
                        names.add(key.getName());
                    }
                for (String tName:threadNames) {
                    if (!names.contains(tName)){
                        if (mWatchDogInterface != null) {
                            mWatchDogInterface.callThreadDead(tName);
                        }
                    }
                }
            } catch (InterruptedException e) {
                logger.error("run: WatchDog thread interrupted");
            }
        }
    }

    //被动检查，不feed 了。
    public synchronized void feed() {
        synchronized (Waiter) {
            mFeeded = true;
            Waiter.notify();
        }
    }

    public void addWatchThreadName(String watchThreadName){
        threadNames.add(watchThreadName);
    }

    public void removeWatchThreadName(String watchThreadName){
        threadNames.remove(watchThreadName);
    }

    //通知被观察线程 没了
    public interface WatchDogInterface{
        void callThreadDead(String str);
    }
}
